import json
import pandas as pd
import numpy as np

from sqlalchemy.orm import Session
from core.response import resp_500
from core.logger import logger
from datetime import datetime, timedelta, date

from app.bill.models.tag_department import TagDepartment
from app.service_quality.models.qos_host_info import QosHostInfo
from app.celery_task.models.celery_task import CeleryTask
from common.aliyun.aliyun_host import AliYunHost
from common.welab_k8s.k8s_node import K8sNode

from setting import config


class QosHostInfoHandler():
    """  HostInfo Handler
    """
    def __init__(self):
        self.aliyun_host = AliYunHost()
        self.k8s_node = K8sNode()



    def get_host_info_search(self, db: Session, quality_date: str, page: int, per_page: int, field: str, value: str):
        """
        根据表字段模糊匹配，获取主机列表信息
        """
        try:
            result = QosHostInfo.get_host_info_search(db, quality_date, page, per_page, field, value)
            if not result:
                logger.error(f"get host info search, result is null => {field}:{value}")
                return False, None

        except Exception as e:
            message = f"get host info search by {field}:{value} error"
            logger.exception(f"{message} => {e}")
            return resp_500(message)

        return True, result




    def get_host_info_match(self, db: Session, quality_date: str, page: int, per_page: int, field: str, value: str):
        """
        根据表字段完全匹配，获取主机列表信息
        """
        try:
            field_info = {"quality_date": quality_date, field: value}
            result = QosHostInfo.filter_by_field_match(db, page, per_page, field_info)
            if not result:
                logger.error(f"get host info match, result is null => {field}:{value}")
                return False, None

        except Exception as e:
            message = f"get host info match by {field}:{value} error"
            logger.exception(f"{message} => {e}")
            return resp_500(message)

        return True, result



    def get_host_info_k8s_node(self):
        k8s_node_infos = self.k8s_node.get_k8s_node_info()
        if not k8s_node_infos:
            logger.error(f"get k8s node info failed, result is null")
            return False
        
        return k8s_node_infos




    def get_classes_name(self, host_info: dict):
        """
        根据标签信息划分归类
        """
        # 大数据集群
        if host_info["tag"] == "p_大数据离线集群":
            return "大数据离线集群"
        if host_info["tag"] == "p_大数据实时集群":
            return "大数据实时集群"

        # k8s集群
        if "k8s" in host_info["tag"]:
            return "k8s集群"

        # 数据库集群
        if host_info["maintain_department"] == "数据库" \
            and host_info["maintain_department"] not in host_info["belong_department"]:
            return "数据库集群"

        return f"{host_info['maintain_department']}部门"




    def task_update_host_info_handle(self, db: Session):
        """
        更新主机信息的处理函数
        """
        try:
            # 获取所以的ecs主机信息
            aliyun_hosts_info = self.aliyun_host.get_all_hosts_info()
            if not aliyun_hosts_info:
                logger.error(f"get aliyun host_info failed")
                return False
            
            # 先删除这个日期的数据，防止重合
            quality_date = date.today().strftime("%Y-%m-%d")
            QosHostInfo.delete_by_quality_date(db, quality_date)
            
            for host_info in aliyun_hosts_info:
                # 增加日期信息
                host_info["quality_date"] = quality_date
                
                # 从标签系统获取相关属性
                tag_department_object = TagDepartment.get_object_by_tag(db, "appname", host_info["tag"])
                if not tag_department_object:
                    logger.error(f"host:{host_info['ip']} tag:{host_info['tag']} not in database")
                    continue
                
                tag_department_info = TagDepartment.get_object_info_by_tag(db, "appname", host_info["tag"])
                host_info["environment"] = tag_department_info["environment"]
                host_info["maintain_department"] = tag_department_info["maintain_department"]
                host_info["belong_department"] = tag_department_info["belong_department"]
                host_info["job_number"] = tag_department_info["job_number"]
                host_info["applicant"] = tag_department_info["applicant"]
                host_info["owner"] = tag_department_info["owner"]
                host_info["expire_time"] = tag_department_info["expire_time"]
                host_info["classes"] = self.get_classes_name(host_info)
                result = QosHostInfo.add(db, host_info)
                if not result:
                    logger.error(f"hostinfo:{host_info['ip']} to database failed")
                    return False
                
        except Exception as e:
            logger.error(f"update host info error=>{e}")
            return False

        logger.info(f"update host info success")
        return True




    def task_update_host_info_start(self, db: Session):
        """
        启动更新主机信息的异步任务
        """
        # 启动异步任务
        from app.service_quality.task import qos_update_host_info_async
        # 判断任务是否已经启动，控制只有一个任务在跑。 如果任务可以多个同时进行，则无需这一步判断。
        task_name = qos_update_host_info_async.name.split(".")[-1]
        if CeleryTask.is_progress_on_name(db, task_name):
            logger.error(f"task: {task_name} was stared")
            return False

        task = qos_update_host_info_async.delay()
        task_data = {
            "name": task_name,
            "tid": task.id,
            "state": task.state
        }

        logger.info(f"add task: {task_name} success")
        return task_data



    def post_host_info_task(self, db: Session):
        """
        启动同步主机信息数据到数据库的异步任务
        """
        try:
            result = self.task_update_host_info_start(db)
            if not result:
                logger.error(f"start task:post_host_info_task failed")
                return False
            
            # result = self.task_update_host_info_handle(db)
            # if not result:
            #     logger.error(f"start task:post_host_info_task failed")
            #     return False

        except Exception as e:
            message = f"start task:post_host_info_task error"
            logger.exception(f"{message} => {e}")
            return resp_500(message)

        return result

